package com.greensoftcodeplus.redislog.utils;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.greensoftcode.MyFun;

import com.greensoftcodeplus.redislog.component.LogDto;
import com.greensoftcodeplus.redislog.properties.MyRedisPropertiesLog;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.util.Locale;
import java.util.Map;


public abstract class ResolvingFun {

    protected static ObjectMapper mapper = new ObjectMapper()
            .setSerializationInclusion(JsonInclude.Include.NON_DEFAULT)
            //  .setSerializationInclusion(JsonInclude.Include.ALWAYS)
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
            .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true);



    public static byte[] SerializeObject(Object o) {
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域，field,get和set,以及修饰符范围，ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型，类必须是非final修饰的，final修饰的类，比如String,Integer等会跑出异常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSeial.setObjectMapper(om);
        byte[] serialize = jacksonSeial.serialize(o);
        return serialize;
    }

    public static String ResolvingArgs(String methodName,Object[] objects) {
        String ret = "";
        methodName=methodName.toUpperCase(Locale.ROOT);
        switch (methodName)
        {
            case  "RPUSH":
            case  "LPUSH":
                for (Object o:objects)
                {    String ret0="";
                     String ret1="";
                      ret0 += ResolvingArgsString.ResolvingArgs(o);
                    if (ret0.equals(""))
                        ret0+= ResolvingArgsObject.ResolvingArgs(o);
                    if (o instanceof byte[][]) {
                       ret1+= ResolvingArgsList.ResolvingArgs(o);
                        if (ret1.equals(""))
                          ret1+= ResolvingArgsArrayObject.ResolvingArrayArgs(o);
                        if (ret1.equals(""))
                            ret1+= ResolvingArgsArrayObject.ResolvingOneArgs(o);
                    }
                    ret+=ret0+ret1;

                }
              break;
            case "HMSET":
                for (Object o:objects) {
                    String ret0 = "";
                    String ret1 = "";
                    ret0 += ResolvingArgsString.ResolvingArgs(o);
                    if (ret0.equals(""))
                        ret0 += ResolvingArgsObject.ResolvingArgs(o);
                    if (o instanceof  Map) {
                       ret1 += ResolvingArgsHash.ResolvingArgs(o);

                    }
                    ret += ret0 + ret1;
                }
                break;
            case "DEL":
                for (Object o:objects) {
                    byte[][] a = (byte[][]) o;
                    String ret0 = new String((byte[]) a[0]);
                    ret += "\""+ret0+"\"";
                }
                break;
            case "HDEL":
                for (Object o:objects) {
                    String ret0="";
                    String ret1="";
                    ret0 += ResolvingArgsString.ResolvingArgs(o);
                    if (ret0.equals(""))
                        ret0+= ResolvingArgsObject.ResolvingArgs(o);
                    if (o instanceof byte[][]) {
                        ret1+= ResolvingArgsArrayString.ResolvingArgs(o);
                    }
                    ret+=ret0+ret1;
                    ;
                }
                break;
            case  "SADD":
                for (Object o:objects)
                {    String ret0="";
                    String ret1="";
                    ret0 += ResolvingArgsString.ResolvingArgs(o);
                    if (ret0.equals(""))
                        ret0+= ResolvingArgsObject.ResolvingArgs(o);
                    if (o instanceof byte[][]) {
                            ret1+= ResolvingArgsArrayString.ResolvingArgs(o);
                    }
                    ret+=ret0+ret1;
                }
                break;
            case "SREM":
                for (Object o:objects)
                {    String ret0="";
                    String ret1="";
                    ret0 += ResolvingArgsString.ResolvingArgs(o);
                    if (ret0.equals(""))
                        ret0+= ResolvingArgsObject.ResolvingArgs(o);
                    if (o instanceof byte[][]) {
                        ret1+= ResolvingArgsArrayObject.ResolvingOneArgs(o);
                    }
                    ret+=ret0+ret1;
                }
                break;

            default:
                for (Object o:objects)
                {
                    String ret0="";
                    ret0+= ResolvingArgsString.ResolvingArgs(o);
                    if (ret0.trim().equals(""))
                    ret0+= ResolvingArgsObject.ResolvingArgs(o);
                    ret+=ret0;
                }
                break;
        }

        return ret;
    }

    public static Object UnSerializeJson(byte[] o) {
        Jackson2JsonRedisSerializer jacksonSeial = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        // 指定要序列化的域，field,get和set,以及修饰符范围，ANY是都有包括private和public
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        // 指定序列化输入的类型，类必须是非final修饰的，final修饰的类，比如String,Integer等会跑出异常
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSeial.setObjectMapper(om);
        Object deserialize = jacksonSeial.deserialize(o);
        return deserialize;
    }

    protected static String UnSerializeSimpleParam(Object obj) {
        if (obj == null)
            return "";
        try {
            if (obj instanceof byte[]  ) {
                obj = new String((byte[]) obj);
                return mapper.writeValueAsString(obj);
            }
            if (obj instanceof Long ) {

                return "\""+mapper.writeValueAsString(obj)+"\"";
            }
            if (obj instanceof Double ) {
                return "\""+mapper.writeValueAsString(obj)+"\"";
            }
            if (obj instanceof  Integer ) {
                return "\""+mapper.writeValueAsString(obj)+"\"";
            }
        } catch (Exception ex) {
            return "";
        }
        return "";
    }
    public void printLogx(LogDto logDto, MyRedisPropertiesLog myProperties) {
        String command = "command:  ";
        command += "\"" + logDto.getMethod().toUpperCase(Locale.ROOT) + "\" ";
        command += logDto.getPara();
        String sql = "======================spring-boot-redis-LogPlus拦截command================\r\n"
                + command + "\r\n" + "执行时间:" + logDto.getCostTime() + "=====================================================\r\n";
        System.out.println(sql);
        String myRedisLogpath = myProperties.getMyRedisLogpath();
        String myRedisLogfilename = myProperties.getMyRedisLogfilename() ;
        MyFun.myLogFileOnlyDays(myRedisLogpath, myRedisLogfilename, sql,myProperties.getMyOnlyDays());
    }

}